package com.berwin.bmfb.utility;

import com.berwin.bmfb.entity.BMChar;
import com.berwin.bmfb.entity.BMFont;
import org.w3c.dom.css.Rect;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class BMFontParser {

    public static BMFont load(String path) throws IOException {
        BMFont bmFont = new BMFont();
        bmFont.setFilePath(path);
        String content = null;
        try {
            content = FileUtility.getStringFromFile(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (content == null)
            return null;
        String lines[] = content.split("\n");
        for (int i = 0; i < lines.length; i++) {
            // 开始解析info
            String line = lines[i];
            Map<String, String> result = null;
            if (line.equals("")) {
                continue;
            } else if (line.startsWith("info ")) {
                result = BMFontParser._parseAttributes(line.replace("info ", ""));
                bmFont.setFace(result.get("face"));
                bmFont.setSize(Integer.parseInt(result.get("size")));
                bmFont.setBold(Integer.parseInt(result.get("bold")));
                bmFont.setItalic(Integer.parseInt(result.get("italic")));
                bmFont.setCharset(result.get("charset"));
                bmFont.setUnicode(Integer.parseInt(result.get("unicode")));
                bmFont.setStretchH(Integer.parseInt(result.get("stretchH")));
                bmFont.setSmooth(Integer.parseInt(result.get("smooth")));
                bmFont.setAa(Integer.parseInt(result.get("aa")));
                bmFont.setPadding(Integer.parseInt(result.get("padding").split(",")[0]));
                bmFont.setSpacing(Integer.parseInt(result.get("spacing").split(",")[0]));
            } else if (line.startsWith("common ")) {
                result = BMFontParser._parseAttributes(line.replace("common ", ""));
                bmFont.setLineHeight(Integer.parseInt(result.get("lineHeight")));
                bmFont.setBaseline(Integer.parseInt(result.get("base")));
                bmFont.setScaleW(Integer.parseInt(result.get("scaleW")));
                bmFont.setScaleH(Integer.parseInt(result.get("scaleH")));
                bmFont.setPages(Integer.parseInt(result.get("pages")));
                bmFont.setPacked(Integer.parseInt(result.get("packed")));
                bmFont.setAlphaChnl(Integer.parseInt(result.get("alphaChnl")));
                bmFont.setRedChnl(Integer.parseInt(result.get("redChnl")));
                bmFont.setGreenChnl(Integer.parseInt(result.get("greenChnl")));
                bmFont.setBlueChnl(Integer.parseInt(result.get("blueChnl")));
            } else if (line.startsWith("editor ")) {
                result = BMFontParser._parseAttributes(line.replace("editor ", ""));
                bmFont.setEditorId(result.get("id"));
                bmFont.setEditorVersion(result.get("version"));
                bmFont.setEditorPadding(Integer.parseInt(result.get("padding")));
                bmFont.setEditorExtSpacing(Integer.parseInt(result.get("extSpacing")));
            } else if (line.startsWith("char ")) {
                // 处理 letter=" " letter="  " letter="   "
                String keyValueStr = line.replace("char ", "");
                keyValueStr = keyValueStr.replace("letter=\" \"", "letter=\"&nbsp;\"");
                keyValueStr = keyValueStr.replace("letter=\"  \"", "letter=\"&nbsp;&nbsp;\"");
                keyValueStr = keyValueStr.replace("letter=\"   \"", "letter=\"&nbsp;&nbsp;&nbsp;\"");
                result = BMFontParser._parseAttributes(keyValueStr);
                BMChar bmChar = new BMChar();
                bmChar.setId(Integer.parseInt(result.get("id")));
                bmChar.setX(Integer.parseInt(result.get("x")));
                bmChar.setY(Integer.parseInt(result.get("y")));
                bmChar.setWidth(Integer.parseInt(result.get("width")));
                bmChar.setHeight(Integer.parseInt(result.get("height")));
                bmChar.setxOffset(Integer.parseInt(result.get("xoffset")));
                bmChar.setyOffset(Integer.parseInt(result.get("yoffset")));
                bmChar.setxAdvance(Integer.parseInt(result.get("xadvance")));
                bmChar.setPage(Integer.parseInt(result.get("page")));
                bmChar.setChnl(Integer.parseInt(result.get("chnl")));
                String letter = result.get("letter");
                if (letter == null)
                    letter = String.valueOf((char) bmChar.getId());
                bmChar.setLetter(letter);
                bmFont.getBmChars().add(bmChar);
            } else if (line.startsWith("chars ")) {
                result = BMFontParser._parseAttributes(line.replace("chars ", ""));
            } else if (line.startsWith("kernings ")) {
                result = BMFontParser._parseAttributes(line.replace("kernings ", ""));
            } else if (line.startsWith("page ")) {
                result = BMFontParser._parseAttributes(line.replace("page ", ""));
                bmFont.setPageId(Integer.parseInt(result.get("id")));
                bmFont.setPageFile(result.get("file"));
            }
//            System.out.println(result.toString());
//            System.out.println();
        }
        BufferedImage bufferedImage = ImageIO.read(new File(bmFont.getPngPath()));
        for (BMChar bmChar : bmFont.getBmChars()) {
            bmChar.setImage(bufferedImage);
        }
        return bmFont;
    }

    public static Map<String, String> _parseAttributes(String content) {
//        System.out.println("content:" + content);
        Map<String, String> result = new HashMap<>();
        String attributeStrings[] = content.split(" ");
        for (int i = 0; i < attributeStrings.length; i++) {
            String attributeString = attributeStrings[i];
            if ("".equals(attributeString))
                continue;
            String keyValues[] = attributeString.split("=");

            keyValues[1] = keyValues[1].replace("\"&nbsp;\"", "\" \"");
            keyValues[1] = keyValues[1].replace("\"&nbsp;&nbsp;\"", "\"  \"");
            keyValues[1] = keyValues[1].replace("\"&nbsp;&nbsp;&nbsp;\"", "\"   \"");
            keyValues[1] = keyValues[1].replace("\"", "");
            result.put(keyValues[0], keyValues[1]);
        }
        return result;
    }

    public static void save(BMFont bmFont, String fntFilePath, String pngFilePath) throws IOException {
        // 获取 Image 对象的高度和宽度
        Rectangle rect = bmFont.getRect();
        bmFont.setScaleW(rect.width);
        bmFont.setScaleH(rect.height);
        String content = "";
        // 第一行
        // info face="number-export" size=32 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1
        int padding = bmFont.getPadding();
        int spacing = bmFont.getSpacing();
        String formater = "info face=\"%s\" size=%d bold=%d italic=%d charset=\"%s\" unicode=%d stretchH=%d smooth=%d aa=%d padding=%d,%d,%d,%d spacing=%d,%d\n";
        content += String.format(formater, bmFont.getFace(), bmFont.getSize(), bmFont.getBold(), bmFont.getItalic(), bmFont.getCharset(), bmFont.getUnicode(), bmFont.getStretchH(), bmFont.getSmooth(), bmFont.getAa(), padding, padding, padding, padding, spacing, spacing);
        // 第二行
        // common lineHeight=20 base=26 scaleW=128 scaleH=64 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0
        formater = "common lineHeight=%d base=%d scaleW=%d scaleH=%d pages=%d packed=%d alphaChnl=%d redChnl=%d greenChnl=%d blueChnl=%d\n";
        content += String.format(formater, bmFont.getLineHeight(), bmFont.getBaseline(), bmFont.getScaleW(), bmFont.getScaleH(), bmFont.getPages(), bmFont.getPacked(), bmFont.getAlphaChnl(), bmFont.getRedChnl(), bmFont.getGreenChnl(), bmFont.getBlueChnl());
        // 第三行
        // page id=0 file="number-export.png"
        formater = "page id=%d file=\"%s\"\n";
        content += String.format(formater, bmFont.getPageId(), bmFont.getPageFile());
        // 第四行
        // chars count=14
        formater = "chars count=%d\n";
        content += String.format(formater, bmFont.getBmChars().size());
        // 第五行 .. n 行
        // char id=52 x=0 y=22 width=16 height=21 xoffset=0 yoffset=-1 xadvance=16 page=0 chnl=0 letter="4"
        for (BMChar bmChar : bmFont.getBmChars()) {
            formater = "char id=%d x=%d y=%d width=%d height=%d xoffset=%d yoffset=%d xadvance=%d page=%d chnl=%d letter=\"%s\"\n";
            content += String.format(formater, bmChar.getId(), bmChar.getX(), bmChar.getY(), bmChar.getWidth(), bmChar.getHeight(), bmChar.getxOffset(), bmChar.getyOffset(), bmChar.getxAdvance(), bmChar.getPage(), bmChar.getChnl(), bmChar.getLetter());
        }
        content += "\n";
        // 第倒数1行
        content += "kernings count=0\n";
        // 保存fnt字体文件
        FileUtility.saveToFile(fntFilePath, content);
        // 保存图片文件

        BufferedImage bi = new BufferedImage(rect.width, rect.height, BufferedImage.TYPE_INT_ARGB);
        Graphics g = bi.getGraphics();
        for (BMChar bmChar : bmFont.getBmChars()) {
            bmChar.drawImage(g, 1, 0);
        }
        //通过 BufferedImage 绘制图像并保存在其对象中
        g.dispose();
        ImageIO.write(bi, "png", new File(pngFilePath));
    }
}
